package org.liveboardgames.agricola.business.action.processor;

import java.util.List;
import java.util.Map;

import org.liveboardgames.agricola.business.updater.FarmTileUpdater;
import org.liveboardgames.agricola.business.updater.FarmUpdater;
import org.liveboardgames.agricola.domain.Change;
import org.liveboardgames.agricola.domain.Game;
import org.liveboardgames.agricola.domain.action.Action;
import org.liveboardgames.agricola.domain.farm.Farm;
import org.liveboardgames.agricola.domain.farm.FarmTile;
import org.liveboardgames.agricola.domain.player.Player;
import org.liveboardgames.agricola.model.enums.ActionOutputEnum;
import org.liveboardgames.agricola.model.enums.FarmElementEnum;
import org.liveboardgames.agricola.model.enums.HouseTypeEnum;

public class RenovationActionProcessor extends ActionProcessor {

  public RenovationActionProcessor(Game game, Action action, List<Change> changes) {
    super(game, action, changes);
  }

  @Override
  public void execute() {
    Player player = (Player)action.getTarget();
    Farm farm = player.getFarm();

    // Get the material into which to renovate
    String newMaterial = getRenovationMaterial(action);

    // Pay the renovation cost
    Map<String, Integer> cost = action.getCost();
    new FarmUpdater(game, farm, changes).pay(cost);

    // Transform the rooms
    for (FarmTile tile : farm.getTiles()) {
      String farmElement = tile.getFarmElement();
      if (FarmElementEnum.isRoom(farmElement)) {
        String newFarmElement = FarmElementEnum.getRoomFromMaterial(newMaterial);
        new FarmTileUpdater(tile, changes).setFarmElement(newFarmElement);
      }
    }
  }

  private String getRenovationMaterial(Action action) {
    String newMaterial = null;

    String output = action.getActionOutput();
    if (ActionOutputEnum.RENOVATION_TO_CLAY.equalsIgnoreCase(output)) {
      newMaterial = HouseTypeEnum.CLAY;
    }
    else if (ActionOutputEnum.RENOVATION_TO_STONE.equalsIgnoreCase(output)) {
      newMaterial = HouseTypeEnum.STONE;
    }
    return newMaterial;
  }

}
